#!/usr/bin/env python
# coding: utf-8

# In[1]:


#Importing PulP solver
from pulp import *


# In[2]:


#Inputing the Demand points
demand_points=['Port of Newcastle','Port of Hedland','Port of Vienna','Port of Mina','Port of Antwerp','Port of Santos','Port of Montreal','Port of Vancouver','Port of Shanghai','Port of Hamburg_Czeck','Port of Alexandria','Port of Marseille','Port of Hamburg_Germany','Port of Budapest','Port of Jawaharlal Nehru','Port of Tanjung Priok','Port of Bandar Abbas','Port of Umm Qasr','Port of Haifa','Port of Gioia Tauro','Port of Nagoya','Port of Aqaba','Port of Busan','Port of Shuwaikh','Port of Beirut','Port of Manzanillo','Port of Rotterdam','Port of Salalah','Port of Gaza','Port of Gdansk','Port of Doha','Port of King Abdul Aziz','Port of Jeddah','Port of Bratislava','Port of Durban','Port of Algeciras','Port of Gothenburg','Port of Latakia','Port of Kaohsiung','Port of Bangkok','Port of Mersin','Port of Jebel Ali','Port of Immingham','Port of New York','Port of Los Angeles','Port of Hodeidah']


# In[3]:


demand_points


# In[6]:


#Inputing the Supply Points
supply_points=['Port of Buenos Aires','Port of Newcastle','Port of Hedland','Port of Baku','Port of Mina Salman','Port of Ploce','Port of Santos','Port of Douala','Port of Montreal','Port of Vancouver','Port of Shanghai','Port of Alexandria','Port of Marseille','Port of Hamburg_Germany','Port of Tema','Port of Piraeus','Port of Budapest','Port of Reykjavik','Port of Jawaharlal Nehru','Port of Tanjung Priok','Port of Bandar Abbas','Port of Gioia Tauro','Port of Nagoya','Port of Aktau','Penang Port','Port of Manzanillo','Port of Belgrade','Port of Maputo','Port of Rotterdam','Port of Tauranga','Port of Lagos','Port of Oslo','Port of Salalah','Port of Gdansk','Port of Doha','Port of Constanta','Port of Vladivostok','Port of Novorossiysk','Port of St. Petersburg','Port of Bratislava','Port of Koper','Port of Durban','Port of Algeciras','Port of Gothenburg','Port of Basel','Port of Riga','Port of Mersin','Port of Odessa','Port of Jebel Ali','Port of Immingham','Port of New York','Port of Los Angeles','Port of Puerto Cabello']


# In[7]:


supply_points


# In[9]:


#Inputing the distances
distance = dict(zip(supply_points,[dict(zip(demand_points, [7087,9900,9783,9420,10946,1078,7874,7508,11098,8105,8607,7282,8105,9669,9312,10113,9112,9691,8747,7606,10707,9083,10985,9646,8704,7342,7827,8169,7282,8820,9355,9476,8921,9771,4596,6504,8275,8631,12452,11538,8606,9168,7877,7248,8833,8382])),
dict(zip(demand_points, [0,3640,11993,8544,11103,7848,10815,6731,5140,13825,9914,11599,13825,11879,6956,4176,8220,8802,9885,10884,4768,9461,5141,8757,9934,6715,13548,7936,9192,14544,8477,8585,8890,11982,6531,11896,12764.72,10099,4693,5436,10095,8290,13598,9689,6466,8351])),
dict(zip(demand_points, [3640,0,9483,6034,8592,8509,13478,7508,3701,11314,7404,9088,11314,9368,4445,1666,5710,6291,7374,8374,4088,6950,3770,6246,7423,8542,11037,5424,6801,12031,5966,6074,6379,9471,5302,9385,11578,7588,3258,3109,7584,5779,11088,12899,7885,5840])),
dict(zip(demand_points, [10919,8699,2581,5574,4813,7846,6651,11888,9681,5084,2384,3121,5084,2468,5504,7770,5292,5787,2497,2500,10267,2853,9981,5767,2500,9571,4816,4443,2600,5454,553,5597,3173,2570,7378,3470,5283,2500,9100,8299,2469,5390,4920,6646,10761,3626])),
dict(zip(demand_points, [8544,6034,5729,0,7193,9662,9594,15871,6882,7561,3650,5332,7561,5615,1589,4660,380,382,3621,4620,7759,3197,7398,310,3670,13061,7284,1253,3178,8277,140,108,2626,5717,4824,5631,7825,3835,6316,5102,3831,327,7334,9168,14552,2087])),
dict(zip(demand_points, [11103,8592,2487,4839,3185,7050,5717,11842,9554,3553,1311,1251,3553,2373,4729,7218,4528,5110,1449,522,10432,1787,10070,5065,1407,9037,3276,3585,1183,4173,5065,4893,2213,2475,6538,1624,3820,1335,8990,7774,6961,4584,3326,5180,10547,2752])),
dict(zip(demand_points, [7848,8509,8705,9662,6658,0,6795,10037,1804,7027,7529,6204,7026,8591,9552,10371,9351,9933,7667,6528,11468,8005,13783,9888,7626,7223,6749,8408,6360,7745,9594,9716,8432,8693,4838,5426,7293,7553,12691,11741,7528,9407,6799,6148,8718,8624])),
dict(zip(demand_points, [9520,8749,7049,8271,5002,4825,7404,10669,11865,5370,5873,4548,5370,6935,8161,8980,7961,8542,6011,4872,12754,6349,12392,8498,5969,7855,5092,7018,5413,5990,8498,8325,6775,7037,3447,3770,5637,5897,11301,10350,9537,8017,5143,6865,9350,7233])),
dict(zip(demand_points, [10815,13478,7098,9594,3334,6796,0,8696,11673,3669,6196,4871,3669,7258,9614,12104,9414,9808,6336,5195,10961,6672,11234,9794,6020,5899,3391,8471,5165,3878,9657,9778,7099,7361,10468,4093,3425,6220,13875,12660,6195,9470,3435,1729,7389,7364])),
dict(zip(demand_points, [6731,7508,13490,15871,11472,8403,8708,0,4956,11819,12322,10996,11819,13383,9428,7279,10381,10848,12461,11320,4321,12797,4517,10828,12441,2814,11541,10461,10365,12534,10603,10668,13108,13486,13733,10218,12082,12345,5419,7026,12320,10440,11591,7051,1319,11270])),
dict(zip(demand_points, [5140,3701,10444,6882,11907,13268,11673,4956,0,12277,8365,10048,12277,10330,5293,2909,6557,7139,8336,9335,1007,7912,535,7094,8385,6843,11999,6270,7660,12993,6814,6922,7341,10432,8418,10346,12539,8550,597,2872,8546,6627,12049,10547,5688,6802])),
dict(zip(demand_points, [9914,7404,2163,3650,3665,7529,6196,12322,8365,4033,0,1805,4034,2047,3540,6030,3340,3921,370,1092,9243,598,8882,3877,427,9534,3756,2397,242,4750,3583,3704,1024,2150,5347,2103,4298,571,7800,6585,546,3396,3806,5618,11025,1563])),
dict(zip(demand_points, [11599,9088,2980,5332,2339,6204,4871,10996,10048,2708,1805,0,2708,2868,5224,7714,5024,5603,1946,730,10928,2282,10566,5558,1900,8209,2430,4081,1631,3425,5267,5388,2709,2971,7032,778,2971,1830,9485,8270,1806,5080,2481,4293,9700,3245])),
dict(zip(demand_points, [13825,11314,5209,7561,426,7027,3669,11819,12277,0,4033,2708,0,5095,7451,9842,7250,7832,4173,3032,13155,4509,12793,7788,4130,9031,341,6307,3595.7,870,7493,7615,4935,5197,8433,1929,417,4057,11711,10496,4032,7306,448,4195,10522,5475])),
dict(zip(demand_points, [9911,9140,6489,8662,4441,11120,6844,10110,12256,4810,5313,3988,4810,6375,8552,9371,8352,8933,5451,4312,13145,5789,12783,8889,5410,7296,4533,7409,4842,5528,8889,8716,6097,6477,3838,3210,5077,5218,11692,10741,9928,8408,4583,6305,8790,6755])),
dict(zip(demand_points, [10498,7988,1688,4234,3208,7072,5739,11864,8949,3477,685,1349,3477,1574,4124,6614,3923,4505,828,635,9827,1182,9465,4460,786,9060,3299,2981,658,4294,4460,4288,1608,1676,5933,1646,3843,696,8385,7169,6356,3980,3349,5203,10570,2147])),
dict(zip(demand_points, [11879,9368,103,5615,4726,8591,7258,13383,10330,5095,2047,2868,5095,0,5505,7995,5304,5886,2192,2154,11208,2563,10846,5841,2148,10565,4817,4362,1992,5812,5547,5669,2989,102,7312,3165,5360,2052,9766,8550,2028,5360,4868,6728,12056,3528])),
dict(zip(demand_points, [14346,11835,5567,7980,1485,6486,2506,9895,12797,1473,4389,3065,1473,5453,7866,10462,7640,8047,4529,3389,13675,4928,13314,8112,4487,7114,1453,6666,3892,1761,8117,8032,5293,5555,8372,2288,1309,4415,12233,11018,10204,7697,1235,2976,8575,5832])),
dict(zip(demand_points, [6956,4445,5619,1589,7082,9552,9614,9428,5293,7451,3540,5224,7451,5505,0,3071,1265,1847,3510,4510,6171,3086,5810,1802,3560,12946 ,7173,1143,3243,8167,1522,1630,2515,5607,4714,5521,7715,3725,4727,3513,3720,1335,7224,9036,10104,1977])),
dict(zip(demand_points, [4176,1666,8109,4660,9572,10371,12104,7279,2909,9842,6030,7714,9842,7995,3071,0,4336,4917,6000,7000,3787,5576,3426,4873,6049,8920,9663,4050,5814,10657,4592,4700,5005,8097,5533,8011,10205,6215,2343,1449,6210,4405,9714,11525,7910,4466])),
dict(zip(demand_points, [8220,5710,5419,380,6882,9351,9414,10381,6557,7250,3340,5024,7250,5304,1265,4336,0,581,3310,4310,7435,2886,7074,537,3359,12745,6973,943,2922,7967,355,365,2315,5407,4514,5321,7514,3524,5991,4778,3520,173,7023,8862,11057,1776])),
dict(zip(demand_points, [10884,8374,2268,4620,2663,6528,5195,11320,9335,3032,1092,730,3032,2154,4510,7000,4310,4891,1230,0,10213,1568,9852,4847,1189,8533,2754,3367,1336,3749,4553,4674,1994,2256,6317,1102,3295,1116,8771,7555,1091,4366,2805,4617,10024,2533])),
dict(zip(demand_points, [4768,4088,11322,7759,12786,11468,10961,4321,1007,13155,9243,10928,13155,11208,6171,3787,7435,8017,9214,10213,0,8790,612,7972,9263,6131,12877,7148,8308,13871,7692,7800,8219,11310,9308,11224,13418,9428,1498,3750,9424,7505,12927,9835,4992,7680])),
dict(zip(demand_points, [10624,8403,2286,5279,4517,7550,6355,11592,9385,4788,2089,2850,4788,2172,5208,7474,4996,5488,2201,2205,9971,2557,9685,5471,2204,9275,4520,4147,2301,5173,5239,5301,2878,2274,7082,3174,4987,2204,8804,8003,2174,5094,4624,6351,10465,3331])),
dict(zip(demand_points, [5076,2565,7419,3856,8882,10534,9839,7359,3025,9251,5340,7024,9251,7305,2268,950,3532,4113,5310,6310,3903,4886,3542,4069,5359,9149,8973,3245,5210,9970,3788,3896,4315,7407,5695,7321,9517,5525,2461,1246,5520,3601,9024,9024,8035,3777])),
dict(zip(demand_points, [6715,8542,10679,13061,8663,7223,5899,2814,6843,9031,9534,8209,9031,10565,12946 ,8920,12745,13332,9673,8533,6131,10011,6404,13286,9631,0,8736,11791,8088,9730,12977,13099,10419,10681,10919,7413,9277,9541,7268,8865,9516,12790,8787,4237,1490,10974])),
dict(zip(demand_points, [11681,9170,301,5416,4528,8392,6786,13207,10132,4897,1851,2668,4897,198,5306,7796,5106,5687,1994,1955,11010,2364,10648,5643,1949,10396,4619,4163,1950,5614,5349,5470,2791,301,7114,2967,5159,1854,9567,8352,1829,5162,4669,6481,11887,3330])),
dict(zip(demand_points, [6949,5084,7165,4563,8354,5126,10638,14022,8200,8722,5086,6770,8722,7050,4452,5315,4252,4833,5056,6056,8023,4632,8077,4789,5105,11207,8445,9144,7237,9441,4789,4616,4061,7153,288,7122,8989,5271,7636,6685,5872,4308,8495,10217,12702,3525])),
dict(zip(demand_points, [13548,11037,4931,7284,144,6749,3391,11541,11999,341,3756,2430,341,4817,7173,9663,6973,7555,3894,2754,12877,4231,12515,7510,3852,8736,0,6030,3335,1058,7216,7338,4658,4920,8156,1652,606,3780,11434,10219,3755,7029,282,3918,10245,5197])),
dict(zip(demand_points, [1414,4854,13202,9753,14665,4737,9582,6162,6349,15033,11123,12807,15033,13087,8164,5385,9429,10010,11093,12093,6013,10669,6349,9965,11142,5633,14756,9144,10251,15761,9965,9793,10098,13190,7883,13104,15300,11307,5901,6645,6015,9498,14807,8456,5644,9559])),
dict(zip(demand_points, [9819,9048,6700,8570,4653,4510,7055,10321,12164,5021,5524,4198,5021,6586,8460,9279,8260,8841,5662,4523,12403,6000,12691,8797,5620,7506,4744,7317,5500,5740,8797,8624,6426,6688,3746,3421,5287,5548,11600,10649,5523,8316,4794,6516,9001,6965])),
dict(zip(demand_points, [14191,11681,5576,7928,793,7393,3521,12184,12643,520,4401,3073,520,5462,7817,10307,7617,8198,4539,3397,13521,4876,13159,8060,4497,9380,708,6675,3831,615,8154,7981,5303,5563,8801,2297,162,4425,12079,10863,10049,7673,813,3955,10791,5842])),
dict(zip(demand_points, [7936,5424,4476,1253,5939,8408,8471,10461,6270,6307,2397,4081,6307,4362,1143,4050,943,1524,2367,3367,7148,1943,6786,1480,2416,11791,6030,0,2086,7025,1186,1307,1372,4464,3571,4378,6418,2582,5704,4490,2577,999,6081,7930,11137,833])),
dict(zip(demand_points, [14544,12031,5926,8277,1143,7745,3878,12534,12993,870,4750,3425,870,5812,8167,10657,7967,8548,4889,3749,13871,5224,13509,8504,4847,9730,1058,7025,4119,0,8213,8334,5654,5915,9152,2649,452,4775,12430,11215,4751,8025,1166,4316,11242,6190])),
dict(zip(demand_points, [8477,5966,5662,140,7125,9594,9657,10603,6814,7493,3583,5267,7493,5547,1522,4592,355,490,3553,4553,7692,3423,7330,421,3602,12977,7216,1186,3139,8213,0,219,2558,5650,4757,5564,7757,3767,6248,5034,3763,187,7267,9392,11279,2019])),
dict(zip(demand_points, [11018,8507,1001,4754,3865,7730,6397,12522,9469,4234,1186,2007,4234,887,4644,7134,4443,5025,1330,1293,10347,1702,9985,4980,1287,9717,3956,3501,1029,4953,4980,4808,2128,989,6453,2304,4500,1192,8905,7689,6876,4499,4007,5861,11227,2667])),
dict(zip(demand_points, [5520,4348,11544,7981,13008,14355,10879,4140,1118,13376,9465,11148,13376,11430,6393,4009,7657,8239,9435,10435,1031,9011,583,8194,9485,6049,13098,7370,8522,14092,7914,8022,8441,11532,9517,11446,13640,9650,1720,3971,9645,7727,13149,9753,4885,7902])),
dict(zip(demand_points, [11406,8893,1312,5139,4251,8117,6782,12907,9854,4619,1572,2392,4619,1197,5029,7519,4829,5410,1715,1678,10732,2087,10371,5366,1672,10103,4342,3886,1295,5338,5072,5193,2680,2513,6839,2689,4885,1577,9290,8074,1552,4885,4392,6246,11613,3052])),
dict(zip(demand_points, [15051,12540,6435,8787,1652,8252,4385,13036,13502,1377,5259,3933,1377,6321,8677,11166,8476,9058,5398,4258,14380,5735,14018,9013,5355,10225,1568,7533,4545,646,8719,8841,6161,6423,9660,3156,960,5283,12938,11722,5258,8532,1674,4824,11600,6700])),
dict(zip(demand_points, [11982,9471,42,5717,4829,8693,7361,13486,10432,5197,2150,2971,5197,102,5607,8097,5407,5988,2293,2256,11310,2665,10949,5944,2250,10681,4920,4464,2243,5915,5650,5771,3092,0,7415,3267,5460,2155,9868,8653,2130,5463,4970,6830,12158,3631])),
dict(zip(demand_points, [11321,8810,2704,5057,3396,7260,3190,12052,9772,3764,1529,1462,3764,2590,4946,10100,4746,5328,1667,732,10650,2005,10288,5283,1625,9248,3486,3803,1364,4483,5283,5111,2431,2693,6756,1834,4030,1553,9208,7992,9842,7366,605,3625,9274,5633])),
dict(zip(demand_points, [6531,5302,7426,4824,8066,4838,10468,13733,8418,8433,5347,7032,8433,7312,4714,5533,4514,5095,5318,6317,9308,4894,8939,5050,5367,10919,8156,3571,7346,9152,4757,4878,4323,7415,0,6834,8698,5534,7930,6941,5530,4572,8207,9902,12410,3786])),
dict(zip(demand_points, [11896,9385,3279,5631,1561,5426,4093,10218,10346,1929,2103,778,1929,3165,5521,8011,5321,5902,2242,1102,11224,2579,10863,5858,2200,7413,1652,4378,2004,2649,5564,5685,3006,3267,6834,0,2195,2127,9782,8567,2102,5377,1703,3515,8922,3545])),
dict(zip(demand_points, [12764.72,11578,5474,7825,690,7293,3425,12082,12539,417,4298,2971,417,5360,7715,10205,7514,8096,4436,3295,13418,4774,13056,8051,4394,9277,606,6418,3775.72,452,7757,7879,5200,5460,8698,2195,0,4323,11978,10763,4299,7573,714,3864,10789,5739])),
dict(zip(demand_points, [12196,9976,0,6851,534,5866,3580,9335,10958,754,3608,2513,754,5260,6780,9047,6568,7061,3812,2837,11543,4129,11257,7044,3821,8124,3369,5720,3662,1124,6812,6874,4450,5360,7394,1814,957,3830,10376,9576,3801,6667,659,3734,8209,4903])),
dict(zip(demand_points, [14788,12277,6171,8523,1388,7989,4122,12803,13239,1114,4995,3670,1114,6057,8413,10903,8213,8794,5135,3994,14117,5471,13755,8750,5092,9993,1304,7270,4325,346,8456,8577,5898,6160,9396,2892,697,5019,12674,11459,4994,8269,1411,4561,11483,6437])),
dict(zip(demand_points, [10095,7584,2142,3831,3664,7528,6195,12320,8546,4032,546,1806,4032,2028,3720,6210,3520,4102,233,1091,9424,778,9062,4057,191,9516,3755,2577,316,4751,3763,3885,1205,2130,5530,2102,4299,89,7981,6766,0,3576,3804,5617,11024,1744])),
dict(zip(demand_points, [11223,7812,1003,4957,4069,7935,6601,12727,9674,4437,1390,2211,4437,889,4847,7337,4647,5228,1533,1496,10552,1905,10190,5184,1490,9922,4160,3704,1181,5156,4890,5011,2332,992,6657,2508,4704,1395,9110,7894,1370,4703,4210,6064,11432,2871])),
dict(zip(demand_points, [8290,5779,5475,327,6938,9407,9470,10440,6627,7306,3396,5080,7306,5360,1335,4405,173,606,3366,4366,7505,2942,7143,562,3415,12790,7029,999,2975,8025,187,389,2371,5463,4572,5377,7573,3580,6063,4847,3576,0,7080,8918,11116,1832])),
dict(zip(demand_points, [13598,11088,4982,7334,313,6799,3435,11591,12049,448,3806,2481,448,4868,7224,9714,7023,7605,3944,2805,12927,4282,12565,7560,3903,8787,282,6081,3399,1166,7267,7388,4708,4970,8207,1703,714,3830,11485,10269,3804,7080,0,3968,10295,5247])),
dict(zip(demand_points, [9689,12899,6839,9168,3827,6148,1729,7051,10547,4195,5618,4293,4195,6728,9036,11525,8862,9417,5756,4617,9835,6104,10108,9392,5715,4237,3918,7930,5196,4316,9392,9222,6521,6830,9902,3515,3864,5642,10972,12081,5617,8918,3968,0,5734,7105])),
dict(zip(demand_points, [6466,7885,12171,14552,10154,8718,7389,1319,5688,10522,11025,9700,10522,12056,10104,7910,11057,11524,11048,10024,4992,11501,5249,11504,11122,1490,10245,11137,9280,11242,11279,11344,11927,12158,12410,8922,10789,11049,6129,7730,11024,11116,10295,5734,0,12465])),
dict(zip(demand_points, [8505,10836,7998,10383,5886,4271,3253,5822,9363,6355,6857,5532,6355,7884,10144,12766,10060,10657,6995,5856,8651,7333,8924,10607,6954,3008,6077,9073,5715,7073,10608,10430,7759,7986,7966,4754,6621,6881,9788,11385,12508,10116,6127,2167,4503,8261]))
]))


# In[10]:


distance


# In[13]:


#Inputing the Aluminium Demand
aluminium_demand=dict(zip(demand_points, [444974.0229,13723699.68,741648.5672,2160942,4070216.374,449431.5,6194339.238,2145005.006,49558405.56,14046489.5,56511,18397487.99,22718776.6,2586223.5,69778081.26,10522502.71,188128.5,12558,2173.5,2511335.897,110175389.6,2363319,79880178.35,3917779.675,34776,3800244,1245285.858,241.5,0,1850060.601,3883561.5,5616265.38,1597339.62,6913017.518,1718272.5,11975505.36,1264630.768,13765.5,6421700.904,23976658.79,10370412.83,304531.5,10472519.99,59911216.55,23352073.24,2415]))


# In[14]:


aluminium_demand


# In[15]:


#Inputing the Aluminium Supply
aluminium_supply=dict(zip(supply_points, [1750417.373,1108486.991,5259760.632,152870.6086,5846232.525,583785.2387,2405044.613,286578.9516,7130120.719,2122464.834,267850261.2,1178963.884,2903970.469,2541200.847,159171.9705,662387.6583,7691376.454,56655403.55,5188197.412,137744624.1,1888157.9,28443.63952,724801.9126,1052630.169,1883968.768,110143.3931,380422.1379,8080791.105,964428.5326,1312543.345,71076.45981,5162036.898,1900360.293,148867.4242,2820733.861,1017712.828,7634624.871,3723801.549,3766639.035,1121081.872,351723.7786,2886609.143,1384623.344,533795.8943,105019.7955,5143227.069,237073.6777,299230.0617,26856798.65,0,
0,0,557404.5143])) 


# In[16]:


aluminium_supply


# In[17]:


# Set Problem Variables
prob = LpProblem("Transportation", LpMinimize)


# In[18]:


prob


# In[19]:


# Set Problem Variables
routes = [(i,j) for i in supply_points for j in demand_points]


# In[20]:


routes


# In[21]:


# Decision Variables
X = LpVariable.dicts("ShipmentAmount",(supply_points, demand_points),0)


# In[22]:


X


# In[23]:


# Objective Function
prob += sum(X[i][j]*distance[i][j] for (i,j) in routes)


# In[24]:


prob


# In[25]:


# Constraints
for j in demand_points:
    prob += sum(X[i][j] for i in supply_points) >= aluminium_demand[j]
    
prob


# In[26]:


# Constraints
for i in supply_points:
    prob += sum(X[i][j] for j in demand_points) == aluminium_supply[i]
prob


# In[27]:


prob.solve()

print("Status:", LpStatus[prob.status])

for v in prob.variables():
    if v.varValue > 0:
        print(v.name, "=", v.varValue)

print("Total kilogram_miles =", value(prob.objective))


# In[ ]:




